/********************************************************/
/*	Copyright (C) 2016 Gong Li Bin			*/
/*	Project:	GlbCloud			*/
/*	Author:		gong_libin			*/
/*	Date:		2012_03_30			*/
/*	File:		MrDb.cpp			*/
/********************************************************/

#include "MrDb.h"

CMrDb::CMrDb()
{
}

CMrDb::~CMrDb()
{
}

void CMrDb::MrDbClose()
{
	m_CTcp.MrNetClose();

	return;
}

int CMrDb::MrDbRecv(MRPROKV_S* pstKv)
{
	CMrPro CPro;
	int iLength = 0;
	USHORT usCount = 0;
	UCHAR* puszCur = NULL;
	UCHAR* puszBody = NULL;
	int iReturn = MR_SUCCESS;
	UCHAR uszHead[MR_PRO_HEAD + MR_PRO_EXPA] = { 0 };

	while (true) {
		if ((iLength = m_CTcp.MrNetRecv(uszHead, MR_PRO_HEAD)) > 0) {
			CPro.MrProReset();
			CPro.MrProParse(uszHead, iLength);
			if (MR_PRO_0 != CPro.MrProGetExpand()) {
				iLength += m_CTcp.MrNetRecv(uszHead + iLength, MR_PRO_EXPA);
			}
			if (CPro.MrProGetLength() > 0) {
				if (NULL != (puszCur = puszBody = (UCHAR*)MrMalloc(sizeof(UCHAR) * CPro.MrProGetLength()))) {
					if ((iLength = m_CTcp.MrNetRecv(puszBody, CPro.MrProGetLength())) > 0) {
						while ((int)(puszCur - puszBody) < iLength) {
							(pstKv + usCount)->m_ucKey = *puszCur;
							(pstKv + usCount)->m_iLength = ntohl(*(int*)(puszCur + sizeof(UCHAR)));
							memcpy((pstKv + usCount)->m_puszValue ,puszCur + MR_PRO_KEYLEN, (pstKv + usCount)->m_iLength);
							puszCur += MR_PRO_KEYLEN + (pstKv + usCount)->m_iLength;
							usCount += 1;
						}
						MrFree((void**)&puszBody);
					}
					else {
						MrFree((void**)&puszBody);
						iReturn = MR_FAILURE;
						break;
					}
				}
				else {
					iReturn = MR_FAILURE;
					break;
				}
			}
			else {
				break;
			}
		}
		else {
			iReturn = MR_FAILURE;
			break;
		}
	}

	return iReturn;
}

int CMrDb::MrDbSend(UCHAR ucVerb, char* pszSql)
{
	CMrPro CPro;
	int iLength = 0;
	UCHAR uszSend[MR_ETHERNET - MR_MACIPTCP] = { 0 };
	MRPROKV_S stKv[] = {{'\0' , 0, NULL}, {'\0', 0, NULL}};

	/* body */
	stKv[0].m_ucKey = ucVerb;
	stKv[0].m_iLength = strlen(pszSql);
	stKv[0].m_puszValue = (UCHAR*)pszSql;
	iLength = MrProKvOutput(stKv, 1, &uszSend[MR_PRO_HEAD], MR_ETHERNET - MR_MACIPTCP);

	/* head */
	CPro.MrProPutBody(NULL);
	CPro.MrProPutVerb(ucVerb);
	CPro.MrProPutAttr(MR_PRO_0);
	CPro.MrProPutReal(MR_PRO_0);
	CPro.MrProPutTotal(MR_PRO_1);
	CPro.MrProPutLength(iLength);
	CPro.MrProPutResult(MR_PRO_0);
	CPro.MrProPutExpand(MR_PRO_0);
	CPro.MrProPutFlag(MR_PRO_FLAG);
	CPro.MrProPutType(MR_DEF_MYSL);
	CPro.MrProPutVersion(MR_PRO_1);
	CPro.MrProPutResponse(MR_PRO_N);
	CPro.MrProPutProtocol(MR_PRO_CTRL);
	CPro.MrProCreate(uszSend, MR_ETHERNET - MR_MACIPTCP);

	return m_CTcp.MrNetSend(uszSend, MR_PRO_HEAD + CPro.MrProGetLength());
}

int CMrDb::MrDbConnect(char* pszAddr, char* pszPort)
{
	if (MR_SUCCESS == m_CTcp.MrTcpConnect(pszAddr, pszPort)) {
		m_CTcp.MrTcpSetLinger(0);
		m_CTcp.MrTcpSetNoDelay();
		m_CTcp.MrNetSetTimeOut(MR_DB_SEC, 0);

	}
	else {
		return MR_FAILURE;
	}

	return MR_SUCCESS;
}
